import React, { useState, useCallback, useEffect, useMemo } from 'react';
import { Picker, PickerView, Input, Popup } from 'antd-mobile';
import { Common } from 'UtilsCommon';
import { Icon } from 'Configs';
import Components from 'Components';
import { useGetDataSourceOptions } from 'UseHooks';
import Base from './base';
import * as styles from '../styles/view.scss';

const getOptions = (property, view, pageAxis, parentValue) => {
    parentValue = parentValue || property.parentValue;

    Base.setValueTextName(property);
    const { valueName, textName } = property;

    const options = [];

    const { dataSource, emptyLabel } = property;

    let value = null; let text = null;
    if (Common.isArray(dataSource)) {
        if (emptyLabel && dataSource.length > 0) options.push({ value: '', label: emptyLabel });

        dataSource.forEach(d => {
            text = d[textName];
            value = d[valueName];

            let isPush = false;
            if (property.judgePush) isPush = property.judgePush(d, parentValue, property, view);
            else isPush = Base.judgePush(d, parentValue, property, view);
            if (isPush) {
                options.push({ value, label: text });
            }
        });
    }

    return options;
};

const getSearchOptions = (options, inputValue) => {
    if (Common.isNullOrEmpty(inputValue)) return options;
    const list = [];
    options.forEach(p => {
        if (p.label.indexOf(inputValue) >= 0) list.push(p);
    });
    return list;
};

const valueChange = (property, view, pageAxis, value) => {
    Base.childPropertiesChanged(property, view, value);
    if (property.valueChange) property.valueChange(value, Base.getSelectData(property, value));

    if (property.selectDataToProperties) Base.setSelectDataToProperties(property, view, Base.getSelectData(property, value));

    if (property.valueChangeEventActionName) {
        if (!Common.isEquals(property.value2, value)) {
            pageAxis.invokeEventAction(property.valueChangeEventActionName, { property, view, pageAxis });
        }
        property.value2 = value;
    }
};

const exists = (options, value) => {
    return !!Common.arrayFirst(options, (f) => Common.isEquals(f.value, value, true));
};

const getText = (options, value) => {
    const item = Common.arrayFirst(options, (f) => Common.isEquals(f.value, value, true));
    if (item === null) return '';
    return item.label;
};

const init = (p) => {
    if (!p.emptyColor) p.emptyColor = '#999999';
    if (!p.emptyLabel) {
        if (p.isCondition) p.emptyLabel = '全部';
        else if (p.isNullable !== false) p.emptyLabel = '不选择（清空）';
    }
};

export default (props) => {
    const { property, view, pageId, pageAxis } = Base.getProps(props);

    useMemo(() => init(property), [property]);
    const [visible, setVisible] = useState(false);
    const [value, setValue] = useState(Base.getInitValue(property));
    const [isVisible, setIsVisible] = useState(property.isVisible !== false);
    const [value3, setValue3] = useState([]);
    const [inputValue, setInputValue] = useState('');

    const [options, setOptions] = useGetDataSourceOptions(property, view, pageAxis, getOptions, property.id);

    const onChange = useCallback((vs) => {
        property.isChanged = true;
        const v = vs[0];
        setValue(v);
        setVisible(false);
        Base.bindDataValue(property, v);
    }, [property, setValue, setVisible]);

    const onChange2 = useCallback(() => {
        property.isChanged = true;
        const v = value3[0];
        setValue(v);
        setVisible(false);
        setValue3([]);
        Base.bindDataValue(property, v);
    }, [property, setValue, setVisible, value3, setValue3]);

    const onChange3 = useCallback((v) => {
        setValue3(v);
    }, [setValue3]);

    const onInputChange = useCallback((v) => {
        setInputValue(v);
    }, [setInputValue]);

    const onCancel = useCallback(() => setVisible(false), [setVisible]);

    const onCancel2 = useCallback(() => { setVisible(false); setValue3([]); }, [setVisible, setValue3]);

    const onShow = useCallback(() => setVisible(!visible), [setVisible]);

    useEffect(() => {
        valueChange(property, view, pageAxis, value);
        if (property.valuePropertyName && !property.valueProperty) {
            property.valueProperty = pageAxis.getViewProperty(property, property.valuePropertyName);
        }
        if (property.valueProperty) {
            const t = value ? property.getText() : property.valueProperty.defaultValue || property.valueProperty.text;
            property.valueProperty.value = t;
            property.valueProperty.setValue && property.valueProperty.setValue(t);
        }
    }, [property, view, pageAxis, value]);

    property.setIsVisible = (v) => { property.isVisible = v; setIsVisible(v); };
    property.setValue = (v) => setValue(v);
    property.getValue = () => Base.getValue(property, value);
    property.getSelectData = () => Base.getSelectData(property, value);
    property.setParentValue = (v) => setOptions(getOptions(property, view, pageAxis, v));
    property.refreshOptions = () => setOptions(getOptions(property, view, pageAxis));
    property.getText = () => getText(options, value);

    if (!isVisible) return null;

    const extra = "请选择" + (property.isNullable === false ? "" : "(可选)");

    const className = Base.getClassName(property, styles);

    const { style, label, labelStyle, isAddColon, isSearch, arrowTop, emptyColor, isValueText, defaultValue, isNullable, isRed } = property;

    const isRed2 = property.isRed2 || (isNullable === false && isRed);

    const label2 = property.isLabel === false ? '' : label;

    let value2 = Common.isNullOrEmpty(value) ? [] : [value];

    if (!exists(options, value)) value2 = [];

    const text = Common.isNullOrEmpty(value) ? extra : isValueText ? value : getText(options, value);

    const textStyle = { ...property.textStyle };
    if (value2.length === 0 && emptyColor) textStyle.color = emptyColor;

    return (
        <React.Fragment>
            <div className={className} style={style}>
                {label2 && <div style={Base.setStyle(labelStyle)}>
                    {isRed2 ? <span style={{ color: 'red', position: 'relative', paddingRight: '0.125rem', top: '0.125rem' }}>*</span> : ''}
                    {label2}{isAddColon ? '：' : ''}
                </div>}
                <div style={Base.setStyle(textStyle)} className='buttonActive' onClick={onShow}>
                    {!property.properties && text}
                    {!property.properties && <Icon type='right' style={{ position: 'relative', top: arrowTop }} color={textStyle.color} fontSize={textStyle.fontSize} />}
                    {property.properties && Components.Base.renderProperties(property, pageId)}
                </div>
            </div>
            {!isSearch && <Picker value={value2}
                onConfirm={onChange}
                onCancel={onCancel}
                columns={[options]}
                title={label}
                visible={visible}
                defaultValue={defaultValue}>
            </Picker>}

            {isSearch && <Popup visible={visible}
                onMaskClick={onCancel2}
                onClose={onCancel2}>
                <div className='divPickerTitle'>
                    <div className='divButton' onClick={onCancel2}><span>取消</span></div>
                    <div className='divText'><span>{label}</span></div>
                    <div className='divButton' onClick={onChange2}><span>确定</span></div>
                </div>
                <div className='divPickerInput'>
                    <Input placeholder='关键字筛选' clearable={true} type='text' value={inputValue} onChange={onInputChange} />
                </div>
                <PickerView value={value3.length === 0 ? value2 : value3}
                    onChange={onChange3}
                    columns={[getSearchOptions(options, inputValue)]}
                    defaultValue={defaultValue}>
                </PickerView>
            </Popup>}
        </React.Fragment>
    );
};